/**
 * 引入第三方js
 */
import GBK from './gbk2.min.js'
import CryptoJS from 'crypto-js'
import {
  transitMsg
} from '@/api/core'
import {
  getServerData
} from '@/api/system'
import {
  ParamArr,
  SQLTable
} from './paramarr'
import {
  hex_md5
} from './md5'
import {
  Test2 as test2
} from '@/api/user'
import {
  userVerify
} from '@/api/user'
import XLSX from 'xlsx'
import store from '@/store'
import moment from 'moment'

/*
 * ******************************************** 全局变量 **************************************
 * *******************************************************************************************
 */
// 首页ID
// var aomIndexID = 'index'
export default {
  // 同步后的系统等级颜色数组
  systemLevelColor: [],
  isEnLang: false, // 是否为英文
  mainLanguageObj: {}, // 中英翻译库 对象
  BASEURL: process.env.NODE_ENV === 'production' ? '/CallFunc.aom' : '/devApi', // 服务器请求路径
  isOptLogo: !([55, 66, 67].indexOf(parseInt(sessionStorage.getItem('sysLogoIndex'))) === -1), // 判断是否为运营平台Logo
  getAppPath() {
    var s = window.location.pathname
    var n = (s.split('/')).length - 1
    var path = ''
    for (var i = 1; i < n; i++) {
      path = path + '../'
    }
    return path
  },

  /**
   * 获取当前服务器是否使用了utf8字符
   */
  getIsEncodingUTF8() {
    return sessionStorage.getItem('isEncodingUTF8') === 'true'
  },

  /*
   * 字符串转换为十六进制
   * @param str
   * @return 十六进制字符串
   */
  stringToHex(str) {
    let arr = []
    if (this.getIsEncodingUTF8()) {
      arr = this.encodeUtf8(str)
    } else {
      arr = GBK.encode(str)
    }
    let val = ''
    for (let i = 0; i < arr.length; i++) {
      let hex = arr[i].toString(16)
      if (hex.length === 1) {
        hex = '0' + hex
      }
      val += hex
    }
    return val
  },

  /*
   * UTF-8编码
   * @param text
   * @return 十六进制字符串
   */
  encodeUtf8(text) {
    const code = encodeURIComponent(text)
    const bytes = []
    for (var i = 0; i < code.length; i++) {
      const c = code.charAt(i)
      if (c === '%') {
        const hex = code.charAt(i + 1) + code.charAt(i + 2)
        const hexVal = parseInt(hex, 16)
        bytes.push(hexVal)
        i += 2
      } else bytes.push(c.charCodeAt(0))
    }
    return bytes
  },

  /*
   * 处理JSON特殊字符
   * @str JSON字符串
   * @return JSON
   */
  parseWebJson(str) {
    if (typeof (str) === 'object') return str
    if (str === '' || str === null || str === undefined) {
      return {}
    }
    str = str.replace(new RegExp('\r', 'gm'), '\\r')
    str = str.replace(new RegExp('\n', 'gm'), '\\n')
    str = str.replace(new RegExp('\t', 'gm'), '\\t')
    return JSON.parse(str)
  },
  getTreeviewPNode(nodeMap, nodes, PID) {
    if (PID !== '') {
      var node = nodeMap.get(PID)
      if (node) {
        if (!node['nodes']) {
          node['nodes'] = []
        }
        return node['nodes']
      }
    }
    return nodes
  },
  /*
   * 十六进制转换为字符串
   * @param hex 十六进制字符串
   * @return string
   */
  hextoString(hex) {
    try {
      var tmp = ''
      if (hex.length % 2 === 0) {
        for (var i = 0; i < hex.length; i += 2) {
          tmp += '%' + hex.charAt(i) + hex.charAt(i + 1)
        }
      }
      var str = ''
      str = decodeURIComponent(tmp)
    } catch (err) {
      var arr = hex.split('')
      var out = []
      // eslint-disable-next-line no-redeclare
      for (var i = 0; i < arr.length / 2; i++) {
        const tmps = parseInt('0x' + arr[i * 2] + arr[i * 2 + 1], 16)
        out.push(tmps)
      }
      str = GBK.decode(out)
    }
    return str
  },

  /*
   * 格式化时间
   */
  formatDateTime(fmt, date) { // author: meizz
    var o = {
      'M+': date.getMonth() + 1, // 月份
      'd+': date.getDate(), // 日
      'h+': date.getHours(), // 小时
      'm+': date.getMinutes(), // 分
      's+': date.getSeconds(), // 秒
      'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
      'S': date.getMilliseconds() // 毫秒
    }
    if (/(y+)/.test(fmt)) {
      fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
    }
    for (var k in o) {
      if (new RegExp('(' + k + ')').test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
      }
    }
    return fmt
  },
  /*
   * 字符串转换成Delphi TDateTime
   */
  strToJsDatetime(str) {
    var arr = str.split(' ')
    var arr1 = arr[0].split('-')
    var arr2 = arr[1].split(':')
    return (new Date(parseInt(arr1[0]), parseInt(arr1[1]) - 1, parseInt(arr1[2]), parseInt(arr2[0]), parseInt(arr2[1]), parseInt(arr2[2])))
  },
  /*
   * 秒数相关返回 00:00:00
   */
  getTimeStringBySeconds(iTime) {
    iTime = parseInt(iTime) || 0
    var H = parseInt(iTime / (60 * 60))
    if (H > 0) {
      iTime = iTime - H * 60 * 60
    }
    var N = parseInt(iTime / 60)
    if (N > 0) {
      iTime = iTime - N * 60
    }
    var S = iTime.toString()

    var s1 = H.toString()
    if (s1.length < 2) {
      s1 = '0' + s1
    }
    var s2 = N.toString()
    if (s2.length < 2) {
      s2 = '0' + s2
    }
    var s3 = S.toString()
    if (s3.length < 2) {
      s3 = '0' + s3
    }
    return this.strFormat('{0}:{1}:{2}', s1, s2, s3)
  },

  /*
   * 两个Js相差秒数
   */
  secondsBetweenJs(date1, date2) {
    var r
    if (date1 > date2) {
      r = ((date1.getTime() - date2.getTime()) / 1000)
    } else { // 相差秒数
      r = ((date2.getTime() - date1.getTime()) / 1000)
    } // 相差秒数
    return r
  },
  strToTimeDef(str, def) {
    var arr = str.split(':')
    var rst = 0
    if (arr.length === 3) {
      rst = this.TryEncodeTime(parseInt(arr[0]), parseInt(arr[1]), parseInt(arr[2]), 0)
    }
    if (rst === 0 && def !== undefined) {
      rst = def
    }
    return rst
  },
  TryEncodeTime(Hour, Min, Sec, MSec) {
    var HoursPerDay = 24
    var MinsPerHour = 60
    var SecsPerMin = 60
    var MSecsPerSec = 1000
    var MinsPerDay = HoursPerDay * MinsPerHour
    var SecsPerDay = MinsPerDay * SecsPerMin
    // var SecsPerHour = SecsPerMin * MinsPerHour
    var MSecsPerDay = SecsPerDay * MSecsPerSec
    if ((Hour < HoursPerDay) && (Min < MinsPerHour) && (Sec < SecsPerMin) && (MSec < MSecsPerSec)) {
      const time = (Hour * (MinsPerHour * SecsPerMin * MSecsPerSec) + Min * (SecsPerMin * MSecsPerSec) + Sec * MSecsPerSec + MSec) / MSecsPerDay
      return time
    }
    return 0
  },
  getTime() {
    return this.strToTimeDef(this.formatDateTime('hh:mm:ss', new Date()))
  },
  // 获取任务颜色
  getTaskColorByState(state) {
    switch (state) {
      case '0':
        return '#777' // 禁用
      case '1':
        return '#5bc0de' // 未执行
      case '2':
        return '#337ab7' // 成功
      case '3':
        return '#d9534f' // 失败
      case '4':
        return '#5cb85c' // 执行中
      case '5':
        return '#f0ad4e' // 人工
    }
  },
  // 任务状态
  getStateByIndex(iIndex) {
    switch (iIndex) {
      case 0:
        return '禁用'
      case 1:
        return '未执行'
      case 2:
        return '成功'
      case 3:
        return '失败'
      case 4:
        return '执行中'
      case 5:
        return '手动任务'
    }
  },
  /*
   * 十进制BGR 转 RGB
   * @param 十进制BGR
   * @return RGB(R, G, B)
   */
  num16ToRGB(sColor) {
    sColor = sColor.toLowerCase()
    var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
    if (sColor && reg.test(sColor)) {
      if (sColor.length === 4) {
        var sColorNew = '#'
        for (var i = 1; i < 4; i += 1) {
          sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
        }
        sColor = sColorNew
      }
      // 处理六位的颜色值
      var sColorChange = []
      for (let i = 1; i < 7; i += 2) {
        sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)))
      }
      return 'RGB(' + sColorChange[2] + ',' + sColorChange[1] + ',' + sColorChange[0] + ')'
    } else {
      return sColor
    }
  },
  /*
   * 十六进制RBG 转 十进制BGR
   * @param 十进制BGR
   * @return BGR
   */
  getColorInt(sColor) {
    if (sColor.indexOf('#') === 0) {
      sColor = sColor.substr(1, sColor.length)
    }
    var r = sColor.substring(0, 2)
    var g = sColor.substring(2, 4)
    var b = sColor.substring(4, 6)
    sColor = b + g + r

    return parseInt(sColor, 16)
  },
  getColor(number, hex) {
    if (typeof number === 'string') {
      number = parseInt(number)
    }
    // 解决后台数据库默认值为空的特例
    if (number === 536870911) number = 0
    number = number.toString(16)
    var match = 6 - number.length
    for (var i = 0; i < match; i++) {
      var str = '0'
      number = str.concat(number)
    }
    number = '#'.concat(number)
    if (hex !== undefined && hex === true) {
      return this.strFormat('#{0}{1}{2}', number.substr(5, 2), number.substr(3, 2), number.substr(1, 2))
    }
    return this.num16ToRGB(number)
  },
  /**
   * @description 通过状态级别获取颜色
   * @param {Object} level 等级
   */
  getLevelIndex(level) {
    let r
    switch (level) {
      case '正常':
        r = 0
        break
      case '离线':
        r = 1
        break
      case '未知':
        r = 2
        break
      case '提示':
        r = 3
        break
      case '警告':
        r = 4
        break
      case '次要':
        r = 5
        break
      case '主要':
        r = 6
        break
      case '严重':
        r = 7
        break
      case 'Normal':
        r = 0
        break
      case 'Offline':
        r = 1
        break
      case 'Unknown':
        r = 2
        break
      case 'Hint':
        r = 3
        break
      case 'Warning':
        r = 4
        break
      case 'Secondary':
        r = 5
        break
      case 'major':
        r = 6
        break
      case 'Error':
        r = 7
        break
      default:
        r = 2
    }
    return r
  },
  getLevelColor(level) {
    if (typeof level === 'string') {
      level = this.getLevelIndex(level)
    }
    if (this.systemLevelColor.length !== 0) {
      return parseInt(this.systemLevelColor[level])
    }
    let r
    switch (level) {
      case 0:
        r = 6076508
        break
      case 1:
        r = 8421504
        break
      case 2:
        r = 12615935
        break
      case 3:
        r = 16711680
        break
      case 4:
        r = 128
        break
      case 5:
        r = 16753920
        break
      case 6:
        r = 8388736
        break
      case 7:
        r = 5198809
        break
      default:
        r = 6076508
        break
    }
    return r
  },
  /*
   * 格式化输出等级文字
   * @level 等级
   * @return “正常”… 等级文字
   */
  getLevelText(level) {
    if (typeof level === 'string') {
      level = parseInt(level)
    }
    let r
    switch (level) {
      case 0:
        r = '正常'
        break
      case 1:
        r = '离线'
        break
      case 2:
        r = '未知'
        break
      case 3:
        r = '提示'
        break
      case 4:
        r = '警告'
        break
      case 5:
        r = '次要'
        break
      case 6:
        r = '主要'
        break
      case 7:
        r = '严重'
        break
      default:
        r = '未知'
    }
    return r
  },
  getRowState(sState) {
    switch (sState) {
      case '未执行':
        return 'info'
      case '正在执行':
        return 'warning'
      case '执行成功':
        return 'success'
      case '代理离线':
        return 'info'
      case '异常退出':
        return 'danger'
      case '执行失败':
        return 'danger'
      case '执行完成':
        return 'success'
      default:
        return 'danger'
    }
  },
  // 树移动状态
  integer(type) {
    if (type === 'before') {
      return 1
    } else if (type === 'after') {
      return 2
    } else if (type === 'inner') {
      return 4
    }
  },
  /*
   * 字串符 格式化
   * 调用方式
   * var str = strFormat("我是{0}，今年{1}了", "loogn",22);
   */
  strFormat() {
    if (arguments.length === 0) {
      return null
    }

    var str = arguments[0]
    for (var i = 1; i < arguments.length; i++) {
      var re = new RegExp('\\{' + (i - 1) + '\\}', 'gm')
      str = str.replace(re, arguments[i])
    }
    return str
  },

  /*
   * 获取两个字符串时间相差，返回 00:00:00
   */
  getTimeStringByDatetime(str1, str2) {
    if (str1 === '' || str2 === '') {
      return ''
    }
    var date1 = this.strToJsDatetime(str1)
    var date2 = this.strToJsDatetime(str2)

    return this.getTimeStringBySeconds(this.secondsBetweenJs(date1, date2))
  },
  IsLeapYear(Year) {
    return ((Year % 4 === 0) && ((Year % 100 !== 0) || (Year % 400 === 0)))
  },
  TryEncodeDateTime(Year, Month, Day) {
    var DayTable = []
    if (this.IsLeapYear(Year)) {
      DayTable = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    } else {
      DayTable = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    }

    if ((Year >= 1) && (Year <= 9999) && (Month >= 1) && (Month <= 12) && (Day >= 1) && (Day <= DayTable[Month])) {
      for (var I = 1; I < Month; I++) {
        Day += DayTable[I]
      }
      I = Year - 1
      var date = I * 365 + parseInt(I / 4) - parseInt(I / 100) + parseInt(I / 400) + Day - 693594 /* DateDelta*/
      return date
    }
    return 0
  },
  /*
   * 字符串转换成Delphi TDate
   */
  strToDateDef(str, def) {
    var arr = str.split('-')
    var rst = 0
    if (arr.length === 3) {
      rst = this.TryEncodeDateTime(parseInt(arr[0]), parseInt(arr[1]), parseInt(arr[2]))
    }
    if (rst === 0 && def !== undefined) {
      rst = def
    }
    return rst
  },
  /*
   * 获取当前delphi格式日期
   */
  getDate() {
    return this.strToDateDef(this.formatDateTime('yyyy-MM-dd', new Date()))
  },
  /*
   * ******************************************** 消息推送 ****************************************
   * *******************************************************************************************
   */
  /*
   * 注册消息
   * obj          处理实例
   * messages     消息数组
   * isReg        是否通知Server，只用main.html首次不需要。默认 true
   */
  mainMessagesReg(obj, messages, isReg) {
    top.mainMessages.regMessages(obj, messages, isReg)
  },

  /*
   * ******************************************** 多页签 ****************************************
   * *******************************************************************************************
   */
  mainPagesCloseSelf() {
    document.querySelector('#tags-view-container .tags-view-item.active .el-icon-close').click()
  },
  /**
   * @description 表格数据量大时使用 优化加载速度
   * @param {Object} table table数据
   * @param {Object} $table $表格元素
   */
  // initAsynDisposeData(tableData, $table, getRow) {
  //   // 异步线程脚本
  //   function asyn() {
  //     self.onmessage = function(e) {
  //       var table = JSON.parse(e.data)
  //       var rows = []
  //       for (var i = table.dataRow; i < table.rowCount; i++) {
  //         rows.push(table.dataJson[i + 1])
  //         if (i % 10 === 0 || i === table.rowCount - 1) {
  //           self.postMessage(rows)
  //           rows = []
  //         }
  //       }
  //       self.postMessage({ isEnd: true })
  //       self.close()
  //     }
  //   }

  //   var jsText = asyn.toString() + 'asyn()'
  //   var blob = new Blob([jsText])
  //   var jsUrl = window.URL.createObjectURL(blob)
  //   var worker = new Worker(jsUrl)
  //   worker.postMessage(JSON.stringify(tableData))
  //   var rows = []
  //   var firstRow = [tableData.dataJson[0]]
  //   worker.onmessage = function(e) {
  //     if (e.data.isEnd === true) {
  //       $table.bootstrapTable('load', rows)
  //       freeStateMsg()
  //       return
  //     }
  //     var arr = firstRow.concat(e.data)
  //     var table = new paramarr.SQLTable(arr, 1)
  //     table.first()
  //     while (!table.eof()) {
  //       var s = getRow(table) // 需要自己定义的 方法 用与处理row数据格式
  //       rows.push(s)
  //       // next
  //       table.next()
  //     }
  //   }
  // },
  // 彩色目录图标 展开
  nodeExpandIcon_new: 'iconfolder_open',
  // 彩色目录图标 关闭
  nodeCollapseIcon_new: 'iconfolder_close',
  // tree节点 text字段 前面添加 多彩图标
  fmtTreeviewNodeText(text, icon, style, attr) {
    icon === undefined && (icon = this.nodeCollapseIcon_new)
    icon = this.strFormat('<svg class="icon-svg" aria-hidden="true"><use xlink:href="#{0}"></use></svg>', icon)
    return this.strFormat("{1}<span {3} style='{2}' id=\"a\">{0}</span>", text, icon, style, attr)
  },
  // 获取机器系统图标字符串
  getSystemIconStr(iType) {
    var systemObj = {
      Windows: 'Windows',
      Unix: 'Unix',
      Linux: 'linux',
      Aix: 'Aix',
      AS400: 'AS400',
      交换机: 'jiaohuanji',
      路由器: 'luyouqi',
      防火墙: 'fanghuoqiang',
      存储设备: 'a-94_cunchushebei',
      负载均衡: 'fuzaijunheng',
      Android: 'anzhuo',
      IOS: 'ios'
    }
    return systemObj[iType] || 'folder' // 'iconother';
  },
  // 获取中文字符串对应的英文
  getENStr(str) {
    if (!this.isEnLang) return str
    if (this.mainLanguageObj !== undefined) {
      return this.mainLanguageObj.getEnStr(str)
    } else if (parent.this.mainLanguageObj !== undefined) {
      return parent.this.mainLanguageObj.getEnStr(str)
    }
    return str
  },
  /*
   * ***************************************** 加密函数 ***************************************************
   * ****************************************************************************************************
   */
  // DES ECB模式解密
  CKEY: '19861026',
  // 函数(需要引用crypto-js.js)
  encryptByDES(message, key) {
    // 把私钥转换成16进制的字符串
    var keyHex = CryptoJS.enc.Utf8.parse(key)
    // 模式为ECB padding为Pkcs7
    var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.ZeroPadding
    })
    // 加密出来是一个16进制的字符串
    return encrypted.ciphertext.toString()
  },
  decryptByDESModeEBC(ciphertext, key) {
    // 把私钥转换成16进制的字符串
    var keyHex = CryptoJS.enc.Utf8.parse(key)
    // 把需要解密的数据从16进制字符串转换成字符byte数组
    var decrypted = CryptoJS.DES.decrypt({
      ciphertext: CryptoJS.enc.Hex.parse(ciphertext)
    }, keyHex, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.ZeroPadding
    })
    // 以utf-8的形式输出解密过后内容
    return decrypted.toString(CryptoJS.enc.Utf8)
  },

  desEtStr(S) {
    if (!S) {
      return ''
    } else {
      return this.encryptByDES(S, this.CKEY)
    }
  },
  desDtStr(S) {
    if (!S) {
      return ''
    } else {
      return this.decryptByDESModeEBC(S, this.CKEY)
    }
  },
  getGuid(isToLow) {
    var s = []
    var hexDigits = '0123456789abcdef'
    for (var i = 0; i < 32; i++) {
      s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
    }
    s[12] = '4' // bits 12-15 of the time_hi_and_version field to 0010
    s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1) // bits 6-7 of the clock_seq_hi_and_reserved to 01
    var guid = s.join('')
    return isToLow ? guid : guid.toUpperCase()
  },
  SameText(str1, str2) {
    if (str1 === null || str2 === null) return false
    return (str1.length !== 0 && str2.length !== 0 && str1.toLowerCase() === str2.toLowerCase())
  },
  callClientFunc(sClientId, uMsg, beforeDMName, beforeLPName, alterDMName, alterLPName, vPar, options) {
    // 默认显示报错信息
    if (!options) {
      options = {
        isShowErrorMsg: true
      }
    }
    return new Promise((resolve, reject) => {
      vPar.setStr('ClientID', sClientId)
      vPar.setMsgId(uMsg)
      vPar.setStr('SrcDMName', beforeDMName)
      vPar.setStr('SrclpName', beforeLPName)
      vPar.setStr('SrcDMName2', alterDMName)
      vPar.setStr('SrclpName2', alterLPName)
      transitMsg(vPar, options).then(vPar => {
        resolve(vPar)
      }).catch(err => {
        reject(err)
      })
    })
  },
  getEventState(state) {
    if (typeof state === 'string') {
      state = parseInt(state)
    }
    switch (state) {
      case 0:
        return '未处理'
      case 1:
        return '已处理'
      case 2:
        return '忽略'
      case 3:
        return '压制'
      case 4:
        return '已处理(异常)'
      default:
        return '未处理'
    }
  },
  /**
   * @description 自定义封装从服务器下载文件兼容IE支持BLOB
   * @param {Object} url 下载请求地址
   * @param {Object} name 文件命名
   */
  downServerFile(url, name) {
    if (url) {
      url = encodeURIComponent(url).replace(/%2F/g, '/')
    }
    if (!!window.ActiveXObject || 'ActiveXObject' in window) {
      // ie
      var oPow = window.open(url, '', 'width = 1, height = 1, top = 5000, left = 5000 ')
      var isOpen = true // 判断window.open是否被禁用
      try {
        if (oPow == null) {
          isOpen = false
        }
      } catch (err) {
        isOpen = false
      }
      if (!isOpen) {
        // 没禁用window.open采用window.open下载
        while (oPow.document.readyState !== 'complete') {
          if (oPow.document.readyState === 'complete') break
        }
        oPow.document.execCommand('SaveAs', true, name)
        oPow.close()
      } else {
        // 禁用了window.open采用iframe下载
        var oIrame = document.createElement('iframe')
        oIrame.style.width = '0px'
        oIrame.style.height = '0px'
        oIrame.style.opacity = 1
        document.body.appendChild(oIrame)
        oIrame.src = url
        // var IfDoc = oIrame.contentDocument || oIrame.document
        oIrame.onreadystatechange = function() { // IE下的节点都有onreadystatechange这个事件
          if (oIrame.readyState === 'complete') {
            oIrame.execCommand('SaveAs', true, name)
            document.body.removeChild(oIrame)
          }
        }
      }
    } else {
      if (typeof url === 'object' && url instanceof Blob) {
        url = URL.createObjectURL(url) // 创建blob地址
      } else {
        const localHost = process.env.NODE_ENV === 'production' ? location.origin : process.env.VUE_APP_LOCOL_HOST
        url = localHost + '/' + url
      }
      var aLink = document.createElement('a')
      aLink.href = url
      aLink.download = name || '' // HTML5新增的属性，指定保存文件名，可以不要后缀，注意，file:///模式下不会生效
      var event
      if (window.MouseEvent) {
        event = new MouseEvent('click')
      } else {
        if (document.createEvent) {
          event = document.createEvent('MouseEvents')
          event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        }
      }
      aLink.dispatchEvent(event)
    }
  },
  /**
   * 获取系统设置的某个值
   * 入参：nameList-查询数组
   */
  getSystemData(nameList) {
    return new Promise((resolve, reject) => {
      let result = []
      const nodes = []
      const vPar = new ParamArr()
      vPar.setStrList('Item', ['系统设置'])
      getServerData(vPar).then(vPar => {
        const nodeMap = new Map()
        const table = new SQLTable(vPar.getTable('k_environment'))
        table.first()
        while (!table.eof()) {
          const node = {}
          node['pid'] = table.getValueByName('PID')
          node['id'] = table.getValueByName('ID')
          node['name'] = table.getValueByName('Name')
          node['value'] = table.getValueByName('Value')
          node['type'] = table.getValueByName('Type')
          node['defValue'] = table.getValueByName('DefValue')
          node['loginID'] = table.getValueByName('LoginID')
          nodes.push(node)
          nodeMap.set(node['name'], node)
          table.next()
        }
        for (let i = 0; i < nameList.length; i++) {
          result.push(nodeMap.get(nameList[i]))
        }
        if (result.length === 0) result = nodes
        resolve(result)
      }).catch(() => {
        reject()
      })
    })
  },
  /**
   * 格式化输出时间
   * @s 毫秒
   * @return h小时m分钟s秒ms毫秒
   */
  TickToTimeStr(t) {
    if (t === 0) {
      return this.strFormat('{0} ' + this.getENStr('毫秒'), '0')
    } else if (t < 1000) {
      return this.strFormat('{0} ' + this.getENStr('毫秒'), t)
    } else if (t < 60000) {
      return (parseInt(t / 1000) + ' ' + this.getENStr('秒')) + this.TickToTimeStr(t % 1000)
    } else if (t < 3600000) {
      return (parseInt(t / 60000) + ' ' + this.getENStr('分钟')) + this.TickToTimeStr(t % 60000)
    } else {
      return (parseInt(t / 3600000) + ' ' + this.getENStr('小时')) + this.TickToTimeStr(t % 3600000)
    }
  },
  getTargetValue(table) {
    switch (table.getIntByName('vaType')) {
      case 0:
        return table.getValueByName('sValue')
      case 1:
        return table.getValueByName('iValue')
      case 2:
        return table.getValueByName('fValue')
      case 3:
        return '(BLOB)'
      case 4:
        return table.getValueByName('lValue')
      default:
        return ''
    }
  },
  QuotedStr(S) {
    return "'" + S + "'"
  },
  // 字符串md5加密 默认返回大小字符串
  MD5(str, toLowerCase) {
    const res = hex_md5(str)
    if (toLowerCase) return res
    return res.toUpperCase()
  },
  // 单个获取系统配置
  /**
   *
   * @param {*} that 页面this指针
   * @param {*} name 要查询的name
   * @returns
   */
  getSystemConfigByName(that, name) {
    const obj = that.$store.state.systemConfig.SystemConfig.get(name)
    return obj || {}
  },
  openDownloadDialog(url, saveName) {
    if ((!!window.ActiveXObject || 'ActiveXObject' in window)) {
      window.navigator.msSaveOrOpenBlob(url, saveName)
    } else {
      if (typeof url === 'object' && url instanceof Blob) {
        url = URL.createObjectURL(url)
      }
      var aLink = document.createElement('a')
      aLink.href = url
      aLink.download = saveName
      aLink.click()
      aLink.remove()
    }
  },
  sheet2blob(sheet, sheetName) {
    sheetName = sheetName || 'sheet1'
    var workbook = {
      SheetNames: [sheetName],
      Sheets: {}
    }
    workbook.Sheets[sheetName] = sheet // 生成excel的配置项
    var wopts = {
      bookType: 'xlsx', // 要生成的文件类型
      bookSST: false, // 是否生成Shared String Table，官方解释是，如果开启生成速度会下降，但在低版本IOS设备上有更好的兼容性
      type: 'binary'
    }
    var wbout = XLSX.write(workbook, wopts)
    var blob = new Blob([this.s2ab(wbout)], {
      type: 'application/octet-stream'
    }) // 字符串转ArrayBuffer
    return blob
  },
  s2ab(s) {
    var buf = new ArrayBuffer(s.length)
    var view = new Uint8Array(buf)
    for (var i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF
    return buf
  },
  saveToTabe(nodes) {
    var table = []
    var arr = []
    var obj = {}
    // 字段
    for (var i = 0; i < Object.keys(nodes[0]).length; i++) {
      obj = {
        Type: 4,
        Name: Object.keys(nodes[0])[i]
      }
      arr.push(obj)
    }
    table.push(arr)
    // value
    for (let i = 0; i < nodes.length; i++) {
      var values = nodes[i]
      let obj = {}
      const arr = []
      for (var j in values) {
        obj = {
          Value: values[j]
        }
        arr.push(obj)
      }
      table.push(arr)
    }
    return table
  },
  extractFileName(str) {
    var i = str.lastIndexOf('\\')
    if (i !== -1) {
      return str.substring(i + 1)
    } else {
      return str
    }
  },
  // 获取系统配置
  getSystemConfig() {
    return new Promise((resolve, reject) => {
      // 登录成功，设置全局变量SystemConfig， 对应原g_systemConfig
      const nodes = []
      const vPar = new ParamArr()
      vPar.setStrList('Item', ['系统设置'])
      getServerData(vPar).then(vPar => {
        const nodeMap = new Map()
        const nodeMapArr = []
        const table = new SQLTable(vPar.getTable('k_environment'))
        table.first()
        while (!table.eof()) {
          const node = {}
          node['pid'] = table.getValueByName('PID')
          node['id'] = table.getValueByName('ID')
          node['name'] = table.getValueByName('Name')
          node['value'] = table.getValueByName('Value')
          node['type'] = table.getValueByName('Type')
          node['defValue'] = table.getValueByName('DefValue')
          node['loginID'] = table.getValueByName('LoginID')
          nodes.push(node)
          nodeMap.set(node['name'], node)

          nodeMapArr.push(node)
          table.next()
        }
        store.commit('systemConfig/setSystemConfig', nodeMap)
        store.commit('systemConfig/setSystemConfigArr', nodeMapArr)
        resolve(true)
      }).catch((err) => {
        reject(err)
      })
    })
  },
  selfCallback(vPar) {
    return (vPar.getGlobalId() === sessionStorage.getItem('Token') + window.location.pathname)
  },
  getJsonStr(json, name, defValue) {
    if (json) {
      var value = json[name]
      if (value === undefined) {
        if (defValue === undefined) {
          value = ''
        } else {
          value = defValue
        }
      }
      return value
    } else {
      return ''
    }
  },
  setJsonStr(json, name, value) {
    if (value === undefined) json[name] = ''
    else json[name] = value
  },
  // data 需要遍历的数据 id当前行的id 使用例子this.tableData = Global.deleteRow(this.tableData, vPar.getStr('ID'))
  deleteRow(data, id) {
    const newData = data.filter(item => item.id !== id)
    newData.forEach(item => item.nodes && (item.nodes = this.deleteRow(item.nodes, id)))
    return newData
  },
  // 例子：Global.getTreeNode(this.tableData, id) 或 Global.getTreeNode(this.tableData, ['id', id])
  getTreeNode(nodes, param) {
    let result
    if (!Array.isArray(param)) {
      param = ['id', param]
    }
    for (let i = 0; i < nodes.length; i++) {
      if (result) break
      if (nodes[i][param[0]] === param[1]) {
        result = nodes[i]
      } else if (Array.isArray(nodes[i].nodes)) {
        result = this.getTreeNode(nodes[i].nodes, param) || result
      }
    }
    return result ?? {}
  },
  // 例子：Global.addTreeNode(this.tableData, row)
  addTreeNode(nodes, node) {
    let result = false
    if (node.pid === '') {
      nodes.push(node)
    } else {
      for (let i = 0; i < nodes.length; i++) {
        if (result) break
        if (nodes[i].id === node.pid) {
          result = true
          if (!nodes[i].nodes) {
            nodes[i].nodes = []
          }
          nodes[i].nodes.push(node)
        } else {
          result = this.addTreeNode(nodes[i].nodes, node) || result
        }
      }
    }
    return result
  },
  // 例子：Global.updateTreeNode(this.tableData, row, key)
  updateTreeNode(nodes, param, key) {
    key ??= 'id'
    let result = false
    for (let i = 0; i < nodes.length; i++) {
      if (result) break
      if (nodes[i][key] === param[key]) {
        result = true
        nodes[i] = {
          ...nodes[i],
          ...param
        }
      } else if (Array.isArray(nodes[i].nodes)) {
        result = this.updateTreeNode(nodes[i].nodes, param) || result
      }
    }
    return result
  },
  // 例子： Global.deleteTreeNode(this.tableData, id) 或 Global.deleteTreeNode(this.tableData, ['id', id])
  deleteTreeNode(nodes, param) {
    let result = false
    if (!Array.isArray(param)) {
      param = ['id', param]
    }
    for (let i = 0; i < nodes.length; i++) {
      if (result) break
      if (nodes[i][param[0]] === param[1]) {
        result = true
        nodes.splice(i, 1)
      } else if (Array.isArray(nodes[i].nodes)) {
        result = this.deleteTreeNode(nodes[i].nodes, param) || result
      }
    }
    return result
  },
  /*
   * 字符串替换所有出现的字符
   * str 原字符串
   * str1 被替换的字符
   * str2 替换成的字符
   */
  replaceAll(str, str1, str2) {
    return str.replace(new RegExp(str1, 'gm'), str2)
  },
  getJsonInt(json, name, defValue) {
    let value = json[name]
    if (value === undefined) {
      if (defValue === undefined) {
        value = 0
      } else {
        value = defValue
      }
    }
    let rst = parseInt(value)
    if (isNaN(rst)) {
      rst = 0
    }
    return rst
  },
  // 获取时间戳 兼容所有浏览器
  getTimeStamp(day) {
    const re = /(\d{4})(?:-(\d{1,2})(?:-(\d{1,2}))?)?(?:\s+(\d{1,2}):(\d{1,2}):(\d{1,2}))?/.exec(day)
    return new Date(re[1], (re[2] || 1) - 1, re[3] || 1, re[4] || 0, re[5] || 0, re[6] || 0).getTime() / 1000
  },
  /**
   * @description 将后台delphi时间转换为js的时间，因为delphi的时间会比js快8个小时
   * @param {String,Number,Object} time
   * @param {String} fmt 如果是string 类型则可以选择返回的时间格式 如 YYYY-MM-DD HH:mm:ss
   */
  getDelphiToJsTime(time, fmt) {
    let date
    const type = typeof time
    if (type !== 'object') {
      date = new Date(time)
    }
    date.setHours(date.getHours() - 8)
    if (type === 'number') {
      date = date.getTime()
    } else if (type === 'string') {
      date = moment(date).format('YYYY-MM-DD HH:mm:ss')
    }
    return date
  },
  // 获取token
  getToken() {
    return sessionStorage.getItem('Token')
  },
  parseFlowNode(jsonData) {
    var nodeLst = []
    var conLst = []
    var nodeIDLst = []
    var conIDLst = []
    for (var i = 0; i < jsonData[1].length; i++) {
      conIDLst.push(jsonData[1][i]['ID'])
      conLst.push(jsonData[1][i])
    }
    for (let i = 0; i < jsonData[0].length; i++) {
      nodeIDLst.push(jsonData[0][i]['ID'])
      nodeLst.push(jsonData[0][i])
      if (jsonData[0][i]['SubFlow']) {
        for (var j = 0; j < jsonData[0][i]['Con_L']; j++) {
          var sID = this.strFormat('Con_{0}_{1}', jsonData[0][i]['Sub_ID'], j)
          if (jsonData[0][i][sID] !== undefined && jsonData[0][i][sID] !== '') {
            conIDLst.push(sID)
            conLst.push(jsonData[0][i][sID])
          }
          // else {
          //    conLst.push(jsonData[0][i]["Con_" + j]);
          // }
        }
        for (let j = 0; j < jsonData[0][i]['Sub_L']; j++) {
          const sID = this.strFormat('Sub_{0}_{1}', jsonData[0][i]['Sub_ID'], j)
          if (jsonData[0][i][sID] !== undefined && jsonData[0][i][sID] !== '') {
            nodeIDLst.push(sID)
            nodeLst.push(jsonData[0][i][sID])
            var obj = this.parseNewSubNode(jsonData[0][i], jsonData[0][i][sID], nodeLst, conLst, nodeIDLst, conIDLst)
            nodeLst = obj[0]
            conLst = obj[1]
            nodeIDLst = obj[2]
            conIDLst = obj[3]
          }
          // else {
          //    nodeLst.push(jsonData[0][i]["Sub_" + j]);
          //    var obj = parseSubNode(jsonData[0][i]["Sub_" + j], nodeLst, conLst);
          //    nodeLst = obj[0];
          //    conLst = obj[1];
          // }
        }
      }
    }
    var res = [nodeLst, conLst, nodeIDLst, conIDLst]
    return res
  },
  // 判单是否是空对象
  isEmptyObject(e) {
    let t
    for (t in e) {
      return false
    }
    return true
  },
  // 创建a标签并下载
  createFileInputClick(callBack) {
    var input = document.createElement('input')
    input.type = 'file'
    input.onchange = function() {
      callBack(input.files)
    }
    input.click()
  },
  // 获取服务动态key用于 验证密码
  getDESKey(callback) {
    const vPar = new ParamArr()
    test2(vPar).then((vPar) => {
      callback(vPar.getStr('key'))
    })
  },
  // 封装验证用户密码
  verifyUserPassword(userId, pass, callBack) {
    this.getDESKey((key) => {
      const vPar = new ParamArr()
      vPar.setStr('User', userId)
      vPar.setStr('Pass', this.MD5(pass))
      vPar.setStr('PassDES', this.encryptByDES(pass, key))
      userVerify(vPar).then((vPar) => {
        callBack(vPar)
      })
    })
  },
  /**
   * 将kb单位转换为 GB等 单位  例如  1055
   * @param {number} size
   * @returns 返回转换完的字符串
   */
  sizeTostr(size) {
    size = parseFloat(size) || 0
    let data = ''
    if (size < 0.1 * 1024) { // 如果小于0.1KB转化成B
      data = size.toFixed(2) + 'B'
    } else if (size < 0.1 * 1024 * 1024) { // 如果小于0.1MB转化成KB
      data = (size / 1024).toFixed(2) + 'KB'
    } else if (size < 0.1 * 1024 * 1024 * 1024) { // 如果小于0.1GB转化成MB
      data = (size / (1024 * 1024)).toFixed(2) + 'MB'
    } else { // 其他转化成GB
      data = (size / (1024 * 1024 * 1024)).toFixed(2) + 'GB'
    }
    const sizestr = data + ''
    const len = sizestr.indexOf('\.')
    const dec = sizestr.substr(len + 1, 2)
    if (dec === '00') { // 当小数点后为00时 去掉小数部分
      return sizestr.substring(0, len) + sizestr.substr(len + 3, 2)
    }
    return sizestr
  },
  /**
   * @description 用于动态路由页面获取传过来的参数
   * @param {String} id 路由上唯一的id
   * @returns
   */
  getRouteData(vueCom) {
    const id = vueCom.$route.params.id
    if (!id) return {}
    const param = JSON.parse(sessionStorage.getItem(`route_params_${id}` || '{}'))
    if (vueCom.Global.isEmptyObject(param)) return {}
    vueCom.$route.params.repName = param.repName
    vueCom.$route.meta.title = param.repName
    return param.data
  },
  // 十六进制转base64
  sha1_to_base64(sha1) {
    const digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    let base64_rep = ''
    let bit_arr = 0
    let bit_num = 0
    let ascv

    for (var n = 0; n < sha1.length; ++n) {
      if (sha1[n] >= 'A' && sha1[n] <= 'Z') {
        ascv = sha1.charCodeAt(n) - 55
      } else if (sha1[n] >= 'a' && sha1[n] <= 'z') {
        ascv = sha1.charCodeAt(n) - 87
      } else {
        ascv = sha1.charCodeAt(n) - 48
      }

      bit_arr = (bit_arr << 4) | ascv
      bit_num += 4
      if (bit_num >= 6) {
        bit_num -= 6

        base64_rep += digits[bit_arr >>> bit_num]
        bit_arr &= ~(-1 << bit_num)
      }
    }

    if (bit_num > 0) {
      bit_arr <<= 6 - bit_num
      base64_rep += digits[bit_arr]
    }
    var padding = base64_rep.length % 4

    if (padding > 0) {
      for (let n = 0; n < 4 - padding; ++n) {
        base64_rep += '='
      }
    }
    return base64_rep
  },
  // 获取当前登录用户的信息
  getUserInfo() {
    const info = {}
    info.user = sessionStorage.getItem('user')
    info.name = sessionStorage.getItem('username')
    info.roleIds = sessionStorage.getItem('roleIds')
    info.roleNames = sessionStorage.getItem('userRoleNames')
    info.id = sessionStorage.getItem('loginID')
    info.deptName = sessionStorage.getItem('deptName')
    return info
  }
}
